using MediatR;
using Microsoft.Extensions.Logging;
using RBAC.Domain.ProcessManagement;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Write.Api.Application.Command.ProcessManagements;
using System.Transactions;

namespace RBAC.Write.Api.Application.Handler.ProcessManagements
{
    /// <summary>
    /// 新增工艺流程 处理器
    /// </summary>
    public class AddProcessFlowHandler : IRequestHandler<AddProcessFlowCommand, APIResult<int>>
    {
        private readonly IBaseRepository<ProcessFlow> _flowRepo;
        private readonly IBaseRepository<ProcessFlowDetail> _detailRepo;
        private readonly IBaseRepository<ProcessFlowAttachment> _attachRepo;
        private readonly ILogger<AddProcessFlowHandler> _logger;

        public AddProcessFlowHandler(
            IBaseRepository<ProcessFlow> flowRepo,
            IBaseRepository<ProcessFlowDetail> detailRepo,
            IBaseRepository<ProcessFlowAttachment> attachRepo,
            ILogger<AddProcessFlowHandler> logger)
        {
            _flowRepo = flowRepo;
            _detailRepo = detailRepo;
            _attachRepo = attachRepo;
            _logger = logger;
        }

        public Task<APIResult<int>> Handle(AddProcessFlowCommand request, CancellationToken cancellationToken)
        {
            var res = new APIResult<int>();
            try
            {
                // 基础校验
                if (string.IsNullOrWhiteSpace(request.FlowCode))
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "工艺流程编号不能为空";
                    return Task.FromResult(res);
                }
                if (string.IsNullOrWhiteSpace(request.FlowName))
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "工艺流程名称不能为空";
                    return Task.FromResult(res);
                }
                if (request.Status != 0 && request.Status != 1)
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "状态只能是0(禁用)或1(启用)";
                    return Task.FromResult(res);
                }

                // 唯一性校验
                var dupCode = _flowRepo.QueryFirstOrDefault<int>(
                    "SELECT COUNT(1) FROM ProcessFlow WHERE FlowCode = @FlowCode AND IsDeleted = 0",
                    new { request.FlowCode });
                if (dupCode > 0)
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "工艺流程编号已存在";
                    return Task.FromResult(res);
                }
                var dupName = _flowRepo.QueryFirstOrDefault<int>(
                    "SELECT COUNT(1) FROM ProcessFlow WHERE FlowName = @FlowName AND IsDeleted = 0",
                    new { request.FlowName });
                if (dupName > 0)
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "工艺流程名称已存在";
                    return Task.FromResult(res);
                }

                using var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled);

                var now = DateTime.Now;
                var processCount = request.Details?.Count ?? 0;

                // 插入主表
                var insertFlowSql = @"INSERT INTO ProcessFlow
                                        (FlowCode, SystemCode, FlowName, ProcessCount, OwnerUserId, OwnerUserName, DepartmentId, DepartmentName, Status, Remark, CreateTime, CreateUser, IsDeleted)
                                      VALUES
                                        (@FlowCode, @SystemCode, @FlowName, @ProcessCount, @OwnerUserId, @OwnerUserName, @DepartmentId, @DepartmentName, @Status, @Remark, @CreateTime, @CreateUser, @IsDeleted);
                                      SELECT LAST_INSERT_ID();";

                var newId = _flowRepo.QueryFirstOrDefault<int>(insertFlowSql, new
                {
                    request.FlowCode,
                    request.SystemCode,
                    FlowName = request.FlowName,
                    ProcessCount = processCount,
                    request.OwnerUserId,
                    request.OwnerUserName,
                    request.DepartmentId,
                    request.DepartmentName,
                    request.Status,
                    request.Remark,
                    CreateTime = now,
                    CreateUser = "system",
                    IsDeleted = false
                });

                if (newId <= 0)
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "新增失败";
                    return Task.FromResult(res);
                }

                // 明细
                if (request.Details != null && request.Details.Count > 0)
                {
                    var insertDetailSql = @"INSERT INTO ProcessFlowDetail
                                                (FlowId, Sort, ProcessId, ProcessCode, ProcessName, OwnerUserId, OwnerUserName, DepartmentId, DepartmentName, Remark, CreateTime, CreateUser, IsDeleted)
                                              VALUES
                                                (@FlowId, @Sort, @ProcessId, @ProcessCode, @ProcessName, @OwnerUserId, @OwnerUserName, @DepartmentId, @DepartmentName, @Remark, @CreateTime, @CreateUser, @IsDeleted);";

                    foreach (var d in request.Details.OrderBy(x => x.Sort))
                    {
                        _detailRepo.Execute(insertDetailSql, new
                        {
                            FlowId = (long)newId,
                            d.Sort,
                            d.ProcessId,
                            d.ProcessCode,
                            d.ProcessName,
                            d.OwnerUserId,
                            d.OwnerUserName,
                            d.DepartmentId,
                            d.DepartmentName,
                            d.Remark,
                            CreateTime = now,
                            CreateUser = "system",
                            IsDeleted = false
                        });
                    }
                }

                // 附件
                if (request.Attachments != null && request.Attachments.Count > 0)
                {
                    var insertAttachSql = @"INSERT INTO ProcessFlowAttachment
                                                (FlowId, FileName, FileUrl, FileSize, ContentType, UploadTime, UploaderId, UploaderName, Status, Remark, CreateTime, CreateUser, IsDeleted)
                                              VALUES
                                                (@FlowId, @FileName, @FileUrl, @FileSize, @ContentType, @UploadTime, @UploaderId, @UploaderName, @Status, @Remark, @CreateTime, @CreateUser, @IsDeleted);";

                    foreach (var a in request.Attachments)
                    {
                        _attachRepo.Execute(insertAttachSql, new
                        {
                            FlowId = (long)newId,
                            a.FileName,
                            a.FileUrl,
                            a.FileSize,
                            a.ContentType,
                            UploadTime = now,
                            UploaderId = (long?)null,
                            UploaderName = (string?)null,
                            a.Status,
                            a.Remark,
                            CreateTime = now,
                            CreateUser = "system",
                            IsDeleted = false
                        });
                    }
                }

                scope.Complete();

                res.Code = APIEnums.Success;
                res.Data = newId;
                res.Msg = "新增成功";
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "新增工艺流程失败: {Message}", ex.Message);
                res.Code = APIEnums.Error;
                res.Msg = "新增工艺流程异常";
                res.Data = 0;
            }

            return Task.FromResult(res);
        }
    }
}
